home *** CD-ROM | disk | FTP | other *** search
- #include <FileTools.h>
- #include <script.h> // for TruncString
-
- /*-----------------------------------------------------------------*/
- /*------------------------ GLOBAL VARIABLES -----------------------*/
- /*-----------------------------------------------------------------*/
-
- StringPtr gPrevSelectedName = NULL;
- Boolean gDirSelectionFlag = FALSE;
-
- StringPtr TDName; // used in TraverseDirectory
- CInfoPBPtr TDCPB; // used in TraverseDirectory
- OSErr TDErr; // used in TraverseDirectory
-
-
- void RecursiveBuild (long dirID, FDActionProc FileAction,
- FDActionProc FolderAction, void *UserData);
-
- /*-----------------------------------------------------------------*/
- /*---------------------- SF UTILITY ROUTINES ----------------------*/
- /*-----------------------------------------------------------------*/
-
- long DirIDFromFSSpec (FSSpecPtr theSpec)
- /* given a name, parent ID, and volrefnum in theSpec, return */
- /* the directory ID of the directory they specify. Return -1 */
- /* if an error occurs */
- {
- long theID = -1;
- OSErr ErrCode;
-
- CInfoPBPtr PB = (CInfoPBPtr)NewPtrClear(sizeof(CInfoPBRec));
-
- if (PB)
- {
- PB->dirInfo.ioDrDirID = theSpec->parID;
- PB->dirInfo.ioCompletion = NULL;
- PB->dirInfo.ioFDirIndex = 0;
- PB->dirInfo.ioNamePtr = theSpec->name;
- PB->dirInfo.ioVRefNum = theSpec->vRefNum;
-
- if ((ErrCode = PBGetCatInfo (PB, FALSE)) == noErr)
- theID = PB->dirInfo.ioDrDirID;
-
- DisposPtr((Ptr)PB);
- }
-
- return theID;
- }
-
- /*-----------------------------------------------------------------*/
-
- long GetCurrentDirectory (void)
- /* return the current directory */
- {
- return *((long *)0x0398);
- }
-
- /*-----------------------------------------------------------------*/
-
- short GetCurrentVolume (void)
- /* return the current volume */
- {
- return (-1 * (*((short *)0x0214)));
- }
-
- /*-----------------------------------------------------------------*/
-
- void SetCurrentVolume (short newVRefNum)
- /* set the current volume */
- {
- // *((short *)0x0214)) = newVRefNum;
- }
-
- /*-----------------------------------------------------------------*/
-
- void SetCurrentDirectory (long newDirID)
- /* set the current directory */
- {
- *((long *)0x0398) = newDirID;
- }
-
- /*-----------------------------------------------------------------*/
-
- pascal Boolean GetFolderFileFilter (ParmBlkPtr PB, void *myDataPtr)
- /* return true if the passed file/folder is NOT a folder */
- {
- CInfoPBPtr CPB = (CInfoPBPtr)PB;
-
- return ((0x0010 & CPB->dirInfo.ioFlAttrib) == 0);
- }
-
- /*-----------------------------------------------------------------*/
- /*------------------------- GetFolder -----------------------------*/
- /*-----------------------------------------------------------------*/
-
- void SetButtonTitle (Handle theButton, StringPtr theName,
- Rect *itsBounds)
- /* set the title of the button to the specified string */
- {
- short result, width;
- Str255 STemp;
-
- if (gPrevSelectedName)
- DisposPtr ((Ptr)gPrevSelectedName);
- gPrevSelectedName = String2String(theName);
-
- width = (itsBounds->right - itsBounds->left) -
- StringWidth ("\pSelect \"\"") + CharWidth (' ');
- result = TruncString (width, theName, smTruncMiddle);
- PStrCat (255, STemp, 3, "\pSelect \"", theName, "\p\"");
- SetCTitle ((ControlHandle)theButton, STemp);
- ValidRect (itsBounds);
- }
-
- /*-----------------------------------------------------------------*/
-
- pascal short GetFolderDlogHook (short item, DialogPtr theDialog,
- void *myDataPtr)
- {
- typedef StandardFileReply *SFRPtr;
- #define kDirButton 10
-
- short myType;
- Handle myHandle;
- Rect myRect;
- Str255 myName;
- CInfoPBRec myPB;
- SFRPtr mySFRPtr;
- OSErr myErr;
- short retVal = item;
-
- if (GetWRefCon((WindowPtr)theDialog) != (long)(sfMainDialogRefCon))
- return retVal;
-
- GetDItem (theDialog, kDirButton, &myType, &myHandle, &myRect);
- if (item == sfHookFirstCall)
- {
- myPB.hFileInfo.ioCompletion = NULL;
- myPB.hFileInfo.ioNamePtr = (StringPtr)(&myName);
- myPB.hFileInfo.ioVRefNum = GetCurrentVolume();
- myPB.dirInfo.ioFDirIndex = -1;
- myPB.hFileInfo.ioDirID = GetCurrentDirectory();
- myErr = PBGetCatInfo(&myPB, FALSE);
- SetButtonTitle (myHandle, myName, &myRect);
- } // if
- else
- {
- mySFRPtr = (SFRPtr)myDataPtr;
- if (mySFRPtr->sfIsFolder || mySFRPtr->sfIsVolume)
- CopyString (mySFRPtr->sfFile.name, myName);
- else
- {
- myPB.hFileInfo.ioCompletion = NULL;
- myPB.hFileInfo.ioNamePtr = (StringPtr)(&myName);
- myPB.hFileInfo.ioVRefNum = mySFRPtr->sfFile.vRefNum;
- myPB.dirInfo.ioFDirIndex = -1;
- myPB.hFileInfo.ioDirID = mySFRPtr->sfFile.parID;
- myErr = PBGetCatInfo (&myPB, FALSE);
- } // else
-
- if (PStrCmp (myName, gPrevSelectedName) != 0)
- SetButtonTitle (myHandle, myName, &myRect);
-
- switch (item) {
- case kDirButton :
- return sfItemCancelButton;
- break;
- case sfItemCancelButton :
- gDirSelectionFlag = FALSE;
- break;
- } //switch
- } // else
-
- return retVal;
-
- } // GetFolderDlogHook
-
- /*-----------------------------------------------------------------*/
-
- void GetDirectory (StandardFileReply *SFReply)
- {
- SFTypeList myTypes;
- Point myPoint = {-1, -1};
- short myNumTypes = -1;
- ModalFilterYDProcPtr myModalFilter = NULL;
- short myActiveList = -1;
- ActivateYDProcPtr myActivateProc = NULL;
- Str255 myName;
-
- gDirSelectionFlag = TRUE;
- if (gPrevSelectedName)
- DisposPtr((Ptr)gPrevSelectedName);
-
- CustomGetFile (&GetFolderFileFilter,
- myNumTypes,
- myTypes,
- SFReply,
- 12800,
- myPoint,
- &GetFolderDlogHook,
- myModalFilter,
- &myActiveList,
- myActivateProc,
- SFReply);
-
- if (gDirSelectionFlag)
- SFReply->sfGood = TRUE;
-
- if (gDirSelectionFlag && SFReply->sfIsVolume)
- PStrCat (255, myName, 2, SFReply->sfFile.name, "\p:");
- else
- CopyString (SFReply->sfFile.name, myName);
-
- if (gDirSelectionFlag && SFReply->sfIsVolume)
- CopyString (myName, SFReply->sfFile.name);
- else
- if (gDirSelectionFlag)
- CopyString (gPrevSelectedName, SFReply->sfFile.name);
-
- gDirSelectionFlag = FALSE;
- }
-
- /*-----------------------------------------------------------------*/
- /*--------------------- TraverseDirectory -------------------------*/
- /*-----------------------------------------------------------------*/
-
- void TraverseDirectory (FSSpec *Directory, FDActionProc FileAction,
- FDActionProc FolderAction, void *UserData)
- /* Given the specification of a directory, traverse its contents */
- /* recursively, applying FileAction to each file, and FolderAction */
- /* to each folder/directory that is encountered */
- {
- TDErr = noErr;
- TDName = (StringPtr)NewPtrClear(64);
- TDCPB = (CInfoPBPtr)NewPtrClear(sizeof(CInfoPBRec));
-
- if (TDCPB && TDName)
- {
- TDCPB->hFileInfo.ioNamePtr = TDName;
- TDCPB->hFileInfo.ioVRefNum = Directory->vRefNum;
- RecursiveBuild (DirIDFromFSSpec(Directory), FileAction,
- FolderAction, UserData);
- }
-
- if (TDName)
- {
- DisposPtr((Ptr)TDName);
- TDName = NULL;
- }
- if (TDCPB)
- {
- DisposPtr((Ptr)TDCPB);
- TDName = NULL;
- }
- }
-
- /*-----------------------------------------------------------------*/
-
- void RecursiveBuild (long dirID, FDActionProc FileAction,
- FDActionProc FolderAction, void *UserData)
- /* this is the routine which does all of the traversal gruntwork */
- /* for TraverseDirectory */
- {
- short index = 1;
-
- do
- {
- TDCPB->hFileInfo.ioFDirIndex = index;
- TDCPB->dirInfo.ioDrDirID = dirID;
-
- TDErr = PBGetCatInfo(TDCPB, FALSE);
-
- if (TDErr == noErr)
- if (0x0010 & TDCPB->dirInfo.ioFlAttrib)
- { // we have a directory; perform user action
- // on it, then traverse it
- if (FolderAction)
- (FolderAction)(TDCPB, UserData);
- RecursiveBuild (TDCPB->dirInfo.ioDrDirID, FileAction,
- FolderAction, UserData);
- TDErr = noErr;
- }
- else // we have a file; perform user action on it
- if (FileAction)
- (FileAction)(TDCPB, UserData);
-
- index++;
- } while (TDErr == noErr);
- }
-
- /*-----------------------------------------------------------------*/
- /*--------------------- FSSpecFromSFReply -------------------------*/
- /*-----------------------------------------------------------------*/
-
- FSSpecPtr FSSpecFromSFReply (SFReply *SFR)
- /* given a file specification from one of the standard file */
- /* routines, return an FSSpec for use with the low level file */
- /* routines. Return NULL if it cannot be constructed */
- {
- CInfoPBPtr myPB = (CInfoPBPtr)NewPtrClear(sizeof(CInfoPBRec));
- FSSpecPtr fileSpec = NULL;
- OSErr ErrCode;
-
- if (myPB)
- {
- myPB->hFileInfo.ioFDirIndex = 0;
- myPB->hFileInfo.ioVRefNum = SFR->vRefNum;
- myPB->hFileInfo.ioNamePtr = SFR->fName;
- if ((ErrCode = PBGetCatInfo (myPB, FALSE)) == noErr)
- {
- fileSpec = (FSSpecPtr)NewPtrClear(sizeof(FSSpec));
- if (fileSpec)
- FSMakeFSSpec (myPB->hFileInfo.ioVRefNum,
- myPB->hFileInfo.ioFlParID,
- myPB->hFileInfo.ioNamePtr,
- fileSpec);
- }
- }
-
- DisposPtr((Ptr)myPB);
- return fileSpec;
- }
-
- /*-----------------------------------------------------------------*/
- /*---------------------- FSSpecFromCInfo --------------------------*/
- /*-----------------------------------------------------------------*/
-
- FSSpecPtr FSSpecFromCInfo (CInfoPBPtr CB)
- /* construct and return an FSSpec record describing the file/folder */
- /* whose information is passed in the CBInfoRec structure */
- {
- FSSpecPtr fileSpec = NULL;
-
- if (CB)
- {
- fileSpec = (FSSpecPtr)NewPtrClear(sizeof(FSSpec));
- if (fileSpec)
- {
- if (0x0010 & CB->dirInfo.ioFlAttrib) // directory
- FSMakeFSSpec (CB->dirInfo.ioVRefNum,
- CB->dirInfo.ioDrParID,
- CB->dirInfo.ioNamePtr,
- fileSpec);
- else // file
- FSMakeFSSpec (CB->hFileInfo.ioVRefNum,
- CB->hFileInfo.ioFlParID,
- CB->hFileInfo.ioNamePtr,
- fileSpec);
- }
- }
-
- return fileSpec;
- }
-
- /*-----------------------------------------------------------------*/
- /*------------------------ FullPathName ---------------------------*/
- /*-----------------------------------------------------------------*/
-
- StringPtr PathNameFromFSSpec (FSSpecPtr fileID)
- /* given the specification of a file, return its full path name */
- {
- CInfoPBPtr myPB = (CInfoPBPtr)NewPtrClear(sizeof(CInfoPBRec));
- Str63 dirName;
- Str255 fullPath, STemp;
- OSErr myErr;
-
-
- if (!myPB || !fileID)
- return NULL;
-
- fullPath[0] = 0;
- myPB->dirInfo.ioNamePtr = dirName;
- myPB->dirInfo.ioVRefNum = fileID->vRefNum;
- myPB->dirInfo.ioDrParID = fileID->parID;
- myPB->dirInfo.ioFDirIndex = -1;
-
- do
- {
- myPB->dirInfo.ioDrDirID = myPB->dirInfo.ioDrParID;
- myErr = PBGetCatInfo (myPB, FALSE);
- PStrCat (255, STemp, 3, dirName, "\p:", fullPath);
- CopyString (STemp, fullPath);
- } while (myPB->dirInfo.ioDrDirID != fsRtDirID);
-
- DisposPtr((Ptr)myPB);
-
- PStrCat (255, STemp, 2, fullPath, fileID->name);
-
- return String2String (STemp);
- }
-
- /*-----------------------------------------------------------------*/
- /*------------------------ FullPathName ---------------------------*/
- /*-----------------------------------------------------------------*/
-
- StringPtr PathNameFromCInfo (CInfoPBPtr CB)
- /* given the specification of a file, return its full path name */
- {
- FSSpecPtr theSpec;
- StringPtr theName = NULL;
-
- if (!CB)
- return NULL;
-
- theSpec = FSSpecFromCInfo(CB);
-
- if (theSpec)
- {
- theName = PathNameFromFSSpec (theSpec);
- DisposPtr((Ptr)theSpec);
- }
-
- return theName;
- }
-